package com.cloudkinto.service.warehouse.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.bo.warehouse.WarehouseAddBo;
import com.cloudkinto.bo.warehouse.WarehouseQueryBo;
import com.cloudkinto.bo.warehouse.WarehouseUpdateBo;
import com.cloudkinto.common.BeanConvert;
import com.cloudkinto.common.RedisKeyConstants;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;
import com.cloudkinto.dao.WarehouseDao;
import com.cloudkinto.entity.WarehouseDo;
import com.cloudkinto.enumType.common.CountryEnum;
import com.cloudkinto.service.warehouse.WarehouseService;
import com.cloudkinto.vo.warehouse.ChannelWarehouseVo;
import com.cloudkinto.vo.warehouse.CompanyWarehouseVo;
import com.cloudkinto.vo.warehouse.WarehouseRes;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 仓库表 service实现类
 * </p>
 *
 * @author long
 * @since 2024-10-29
 */
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class WarehouseServiceImpl extends ServiceImpl<WarehouseDao, WarehouseDo> implements WarehouseService {
    static HashMap<String, Integer> warehouseStatus = new HashMap<>();
    static HashMap<String, Integer> warehouseType = new HashMap<>();

    static {
        warehouseStatus.put("启用", 0);
        warehouseStatus.put("停用", 1);
        warehouseType.put("自营仓", 0);
        warehouseType.put("代理仓", 1);
    }

    private final RedisTemplate redisTemplate;

    @Override
    public void add(WarehouseAddBo req) {
//        WarehouseDo entityDo = new WarehouseDo();
//        BeanUtils.copyProperties(req, entityDo);
        WarehouseDo entityDo = BeanConvert.INSTANCE.warehouseAddBoToWarehouseDo(req);
        entityDo.setStatus(0);
        baseMapper.insert(entityDo);
    }

    @Override
    public void update(WarehouseUpdateBo req) {
        WarehouseDo entityDo = new WarehouseDo();
//        BeanUtils.copyProperties(req, entityDo);
        BeanConvert.INSTANCE.warehouseUpdateBoToWarehouseDo(req, entityDo);
        baseMapper.updateById(entityDo);
    }


    @Override
    public int delete(Long id, Long userId) {
        return baseMapper.deleteById(id);
    }

    @Override
    public Object detail(Long id) {
        WarehouseDo entityDo = baseMapper.selectById(id);
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return handlerDetailAfter(res);
    }

    /**
     * 查询明细之后要执行的业务定制处理
     */
    private Object handlerDetailAfter(Object res) {
        return res;
    }

    @Override
    public SingleResult<Map<String, Object>> pageInit(Long tenantId) {
        HashMap<String, Object> map = new HashMap<>(8);
        map.put("currencyList", CountryEnum.getCurrencyList());
        map.put("warehouseStatus", warehouseStatus);
        map.put("warehouseType", warehouseType);
        return SingleResult.success(map);
    }

    @Override
    public Long getLastWhId(String source, Long userId, Long tenantId) {
        if (tenantId == null) {
            return -1L;
        }
        List<WarehouseRes> warehouseResList = this.getList(source, userId, tenantId);
        if (CollUtil.isEmpty(warehouseResList)) {
            return -1L;
        }
        List<Long> collect = warehouseResList.stream().map(WarehouseRes::getId).collect(Collectors.toList());
        Map<String, String> whMap = redisTemplate.opsForHash().entries(RedisKeyConstants.WMS_LastLogin_WhId);
        if (whMap.get(userId.toString()) != null && collect.contains(Long.parseLong(whMap.get(userId.toString())))) {
            return Long.parseLong(whMap.get(userId.toString()));
        }
        whMap.put(userId + "", collect.get(0) + "");
        redisTemplate.opsForHash().putAll(RedisKeyConstants.WMS_LastLogin_WhId, whMap);
        return collect.get(0);
    }

    /**
     * source = all 所有仓库
     *
     * @param tenantId
     * @return
     */
    @Override
    public List<WarehouseRes> getList(Long tenantId) {
        if (tenantId == null) {
            return new ArrayList<>();
        }
        WarehouseQueryBo bo = new WarehouseQueryBo();
        bo.setTenantId(tenantId);
        bo.setStatus(0);
//        bo.setUserId(-1L);
        bo.setSource("all");
        return this.getList(bo);
    }

    @Override
    public List<WarehouseRes> getList(String source, Long userId, Long tenantId) {
        if (tenantId == null) {
            return new ArrayList<>();
        }
        WarehouseQueryBo bo = new WarehouseQueryBo();
        bo.setTenantId(tenantId);
        bo.setStatus(0);
        bo.setSource(source);
        bo.setUserId(userId);
        return this.getList(bo);
    }

    @Override
    public List<WarehouseRes> getList(WarehouseQueryBo bo) {
        List<WarehouseDo> list = baseMapper.getListPage(bo);
        return JSONUtil.toList(JSONUtil.toJsonStr(list), WarehouseRes.class);
    }

    @Override
    public PageResult getListPage(WarehouseQueryBo bo) {
        IPage<WarehouseDo> page = new Page<>(bo.getCurrent(), bo.getPageSize());
        List<WarehouseDo> listPage = baseMapper.getListPage(page, bo);
        return new PageResult<>(
                listPage,
                (int) page.getCurrent(),
                (int) page.getSize(),
                (int) page.getTotal(),
                (int) page.getPages()
        );
    }

    private LambdaQueryWrapper<WarehouseDo> queryBuild(WarehouseQueryBo bo) {
        LambdaQueryWrapper<WarehouseDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Objects.nonNull(bo.getTenantId()), WarehouseDo::getTenantId, bo.getTenantId());
        wrapper.like(StrUtil.isNotBlank(bo.getWhCode()), WarehouseDo::getWhCode, bo.getWhCode());
        wrapper.eq(Objects.nonNull(bo.getStatus()), WarehouseDo::getStatus, bo.getStatus());
        wrapper.in(CollUtil.isNotEmpty(bo.getCurrencyCode()), WarehouseDo::getCurrencyCode, bo.getCurrencyCode());
        wrapper.eq(Objects.nonNull(bo.getWarehouseType()), WarehouseDo::getWarehouseType, bo.getWarehouseType());
        wrapper.last(String.format("   and      (case when  (select white_wh from t_user where id = %1$s ) = 0 or '%4$s' = 'all' \n" +
                                   "        then 1=1\n" +
                                   "        ELSE id in (select third_id from t_user_white uw where uw.delete_flag = 0 and uw.user_id = %1$s and uw.type = 'storage') end) " +
                                   "order by %2$s %3$s",

                bo.getUserId(), StringUtils.isNotBlank(bo.getSortName()) ? bo.getSortName() : "id", StringUtils.isNotBlank(bo.getSortOrder()) ? bo.getSortOrder() : "DESC", bo.getSource())
        );
//        if (StrUtil.isNotBlank(bo.getSortName())) {
//            wrapper.last("order by " + bo.getSortName() + " " + bo.getSortOrder());
//        } else {
//            wrapper.orderByDesc(WarehouseDo::getCreateTime);
//        }
        return wrapper;
    }

    /**
     * 获取可用仓库列表 物流渠道设置发货地址用
     */
    @Override
    public List<ChannelWarehouseVo> getWarehouseListForChannel(Long channelId, Long tenantId) {
        return baseMapper.getWarehouseList(channelId, tenantId);
    }


    @Override
    public List<CompanyWarehouseVo> getWarehouseCompanyForAddInit(Long companyId, Long tenantId) {
        List<WarehouseDo> list = this.list(new LambdaQueryWrapper<WarehouseDo>().eq(WarehouseDo::getTenantId, tenantId));
        List<CompanyWarehouseVo> resList = new ArrayList<>();
        for (WarehouseDo et : list) {
            resList.add(new CompanyWarehouseVo(et.getId(), et.getWhCode(), et.getTenantId(), et.getWhNameCn(), et.getCurrencyCode(), 0, et.getStatus()));
        }
        return resList;
    }

    /**
     * 公司可用仓库列表
     */
    @Override
    public List<CompanyWarehouseVo> getWarehouseCompany(Long companyId, Long tenantId) {
        return baseMapper.getWarehouseCompany(companyId, tenantId);
    }

    /**
     * 公司可用仓库列表
     */
    @Override
    public List<WarehouseDo> getWarehouseCompanyDo(Long companyId, Long tenantId) {
        return baseMapper.getWarehouseCompanyDo(companyId, tenantId);
    }

    @Override
    public List<CompanyWarehouseVo> getWarehouseListForBindAddress(Long channelId, Long tenantId) {
        return baseMapper.getWarehouseListForBindAddress(channelId, tenantId);
    }
}
